#pragma once

#include "ClassInfo.h"

bool image_parse::CClassInfo::operator< (const CClassInfo& b)
{
	return Label<b.Label;
}

bool image_parse::CClassInfo::operator== (const CClassInfo& b)
{
	return Label==b.Label;
}

bool image_parse::CClassInfo::InputFromStream(istream& inStream)
{
	if (!(inStream>>Name>>R>>G>>B)) return false;
	CDataStructureTools::ToLowerCase(Name);
	return true;
}

void image_parse::CClassInfo::OuputToStream(ostream& outStream)
{
	outStream<<setw(10)<<Name<<'\t';
	outStream<<setw(3)<<R<<'\t';
	outStream<<setw(3)<<G<<'\t';
	outStream<<setw(3)<<B<<endl;
}

bool image_parse::CClassInfoSet::InputFromFile(string strFN_ClassInfo)
{
	ifstream inFile(strFN_ClassInfo.c_str());
	bool ret = InputFromStream(inFile);
	inFile.clear();
	inFile.close();
	return ret;
}

bool image_parse::CClassInfoSet::InputFromStream(istream& inStream)
{
	int i,t,n;
	CClassInfo tClassInfo;

	if (!(inStream>>n)) return false;

	ClassList.Clear();
	NameMap.clear();

	tClassInfo.Name = "void";
	tClassInfo.R = tClassInfo.G = tClassInfo.B = 0;
	ClassList.PushBack(tClassInfo);
	NameMap[tClassInfo.Name] = 0;

	for ( i = 0; i < n; ++i )
	{
		if (!tClassInfo.InputFromStream(inStream)) return false;
		t = GetLabel(tClassInfo.Name);
		if (t<0)
		{
			NameMap[tClassInfo.Name] = tClassInfo.Label = (int)ClassList.Size;
			ClassList.PushBack(tClassInfo);
		}
		else
		{
			tClassInfo.Label = t;
			ClassList.pElement[t] = tClassInfo;
		}
	}
	return true;
}

int image_parse::CClassInfoSet::GetLabel(string ClassName) const
{
	CDataStructureTools::ToLowerCase(ClassName);
	map<string, int>::const_iterator itr = NameMap.find(ClassName);
	if (itr == NameMap.end())
		return -1;
	else
		return itr->second;
}

int image_parse::CClassInfoSet::GetLabel(int R, int G, int B) const
{
	int i, ret, rv, tv;
	const CClassInfo* pClassInfo = ClassList.pElement;
	ret = -1;
	for ( i = 0; i < (int)ClassList.Size; ++i, ++pClassInfo )
	{
		tv = CMyMath::sqr(R - pClassInfo->R) + CMyMath::sqr(G - pClassInfo->G) + CMyMath::sqr(B - pClassInfo->B);
		if (ret<0 || tv<rv)
		{
			ret = i;
			rv = tv;
		}
	}
	return ret;
}

const image_parse::CClassInfo* image_parse::CClassInfoSet::GetClassInfo(int Label) const
{
	if (Label<0 || Label>=(int)ClassList.Size)
		return NULL;
	else
		return ClassList.pElement + Label;
}

const image_parse::CClassInfo* image_parse::CClassInfoSet::GetClassInfo(string ClassName) const
{
	return GetClassInfo(GetLabel(ClassName));
}

const image_parse::CClassInfo* image_parse::CClassInfoSet::GetClassInfo(int R, int G, int B) const
{
	return GetClassInfo(GetLabel(R, G, B));
}

